#ifndef FIIPFORMAT_H
#define FIIPFORMAT_H
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "./bufRecver.h"
#include "./crc.h"
#include "riselib/mempool.h"

#ifdef __cplusplus
extern "C" {
#endif

#define FRAME_LEN_MAX 256

typedef struct Format_Field {
  uint8_t leading[3];   // 前导
  uint8_t startTag[2];  // 起始标识
  uint8_t srcAddr[8];   // 源地址
  uint8_t dstAddr[8];   // 目标地址
  uint8_t ttl[1];       // 生存时间
  uint8_t type[1];      // 协议类型

  uint8_t version[1];                // 版本号
  uint8_t control[1];                // 控制字段
  uint8_t retransmit[1];             // 重传
  uint8_t reserve1[1];               // 预留1
  uint8_t errno[1];                  // 错误码
  uint8_t index[2];                  // 命令序列号
  uint8_t cmd[2];                    // 命令标识
  uint8_t len[2];                    // 消息体长度
  uint8_t body[FRAME_LEN_MAX - 41];  // 消息体

  uint8_t crc[2];       // CRC校验
  uint8_t endTag[2];    // 结束标识
  uint8_t trailing[3];  // 后继
} Format_FieldStruct;   // 数据结构
typedef enum {
  format_field_leading = 0,
  format_field_startTag = 3,
  format_field_srcAddr = 5,
  format_field_dstAddr = 13,
  format_field_ttl = 21,
  format_field_type = 22,

  format_field_version = 23 + 0,
  format_field_control = 23 + 1,
  format_field_retransmit = 23 + 2,
  format_field_reserve1 = 23 + 3,
  format_field_errno = 23 + 4,
  format_field_index = 23 + 5,
  format_field_cmd = 23 + 7,
  format_field_len = 23 + 9,
  format_field_body = 23 + 11,

  format_field_crc = FRAME_LEN_MAX - 7,
  format_field_endTag = FRAME_LEN_MAX - 5,
  format_field_trailing = FRAME_LEN_MAX - 3,
} Format_FieldEnum;

typedef struct Format {
  BufRecverStruct* bufRecver;
  uint8_t* buf;
  uint16_t* bufLen;
  Format_FieldStruct* msg;
  uint8_t _index[2];
} FormatStruct;  //数据结构

FormatStruct* format_new(void);
void format_del(FormatStruct* self);
void format_setVar(FormatStruct* self,
                   Format_FieldEnum field,
                   uint8_t* data,
                   uint16_t dataLen);
uint8_t* format_getData(FormatStruct* self);
Format_FieldStruct* format_getMsg(FormatStruct* self);

#ifdef __cplusplus
}
#endif
#endif  // FIIPFORMAT_H
